//
//  MZExtensionAttributedString.swift
//  MZTool
//
//  Created by gby on 2022/2/15.
//

import Foundation


extension NSMutableParagraphStyle{
    public convenience init(align:NSTextAlignment) {
        self.init()
        self.alignment = align
    }
}

extension MZKit where Base == NSMutableAttributedString {
    
    public func boundingSize( maxW: CGFloat) -> CGSize {
        let framesetter = CTFramesetterCreateWithAttributedString(base)
        var rangeToSize = CFRangeMake(0, base.length as CFIndex)
        let size = CGSize(width: maxW, height: CGFloat.greatestFiniteMagnitude)
        let path = CGMutablePath()
        path.addRect(CGRect(x: 0, y: 0, width: size.width, height: 1000))
        let frame = CTFramesetterCreateFrame(framesetter, CFRangeMake(0, 0), path, nil)
        let lines = CTFrameGetLines(frame)
        if CFArrayGetCount(lines) > 0 {
            let lastVisibleLineIndex = min(1000, CFArrayGetCount(lines)) - 1
            let lastVisibleLine = unsafeBitCast(CFArrayGetValueAtIndex(lines, lastVisibleLineIndex), to: CTLine.self)
            
            let rangeToLayout = CTLineGetStringRange(lastVisibleLine)
            rangeToSize = CFRangeMake(0, rangeToLayout.location + rangeToLayout.length)
        }
        let suggestedSize = CTFramesetterSuggestFrameSizeWithConstraints(framesetter, rangeToSize, nil, size, nil);
        return CGSize(width: suggestedSize.width, height: suggestedSize.height)
    }
    
    public static func initWith(text: String , font: UIFont, color: UIColor, alignment:NSTextAlignment) -> NSMutableAttributedString{
        let paragraphstyle = NSMutableParagraphStyle.init(align: alignment)
        return NSMutableAttributedString.init(string: text, attributes: [NSMutableAttributedString.Key.font:font,
                                                                    NSMutableAttributedString.Key.foregroundColor:color,
                                                                    NSMutableAttributedString.Key.paragraphStyle:paragraphstyle])
    }
    
    public static func initWith(value:(_ :String, _: UIFont, _: UIColor, _:NSTextAlignment) ,_ style:NSMutableParagraphStyle?) -> NSMutableAttributedString{
        var paragraphstyle = style
        if style == nil {
            paragraphstyle = NSMutableParagraphStyle.init(align: value.3)
        }
        return NSMutableAttributedString.init(string: value.0, attributes: [NSMutableAttributedString.Key.font:value.1,
                                                                    NSMutableAttributedString.Key.foregroundColor:value.2,
                                                                    NSMutableAttributedString.Key.paragraphStyle:paragraphstyle!])
    }
}



extension MZKit where Base == NSAttributedString {
    
    public func boundingSize( maxW: CGFloat) -> CGSize {
        let framesetter = CTFramesetterCreateWithAttributedString(base)
        var rangeToSize = CFRangeMake(0, base.length as CFIndex)
        let size = CGSize(width: maxW, height: CGFloat.greatestFiniteMagnitude)
        let path = CGMutablePath()
        path.addRect(CGRect(x: 0, y: 0, width: size.width, height: 1000))
        let frame = CTFramesetterCreateFrame(framesetter, CFRangeMake(0, 0), path, nil)
        let lines = CTFrameGetLines(frame)
        if CFArrayGetCount(lines) > 0 {
            let lastVisibleLineIndex = min(1000, CFArrayGetCount(lines)) - 1
            let lastVisibleLine = unsafeBitCast(CFArrayGetValueAtIndex(lines, lastVisibleLineIndex), to: CTLine.self)
            
            let rangeToLayout = CTLineGetStringRange(lastVisibleLine)
            rangeToSize = CFRangeMake(0, rangeToLayout.location + rangeToLayout.length)
        }
        let suggestedSize = CTFramesetterSuggestFrameSizeWithConstraints(framesetter, rangeToSize, nil, size, nil);
        return CGSize(width: suggestedSize.width, height: suggestedSize.height)
    }
    
}
